package com.cencat.order.mapper;

import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.cencat.order.entity.Order;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Map;

/**
 * 订单数据访问层
 * 
 * @author cencat
 * @version 1.0
 * @since 2024-01-20
 */
@Mapper
public interface OrderMapper extends BaseMapper<Order> {

    /**
     * 分页查询订单列表
     * 
     * @param page 分页参数
     * @param orderStatus 订单状态
     * @param startTime 开始时间
     * @param endTime 结束时间
     * @param userId 用户ID
     * @return 订单分页数据
     */
    IPage<Order> selectOrderPage(
            Page<Order> page,
            @Param("orderStatus") Integer orderStatus,
            @Param("startTime") LocalDateTime startTime,
            @Param("endTime") LocalDateTime endTime,
            @Param("userId") Long userId
    );

    /**
     * 根据订单号查询订单详情
     * 
     * @param orderNo 订单号
     * @return 订单信息
     */
    Order selectByOrderNo(@Param("orderNo") String orderNo);

    /**
     * 查询用户订单列表
     * 
     * @param userId 用户ID
     * @param orderStatus 订单状态
     * @param limit 限制数量
     * @return 订单列表
     */
    List<Order> selectByUserId(
            @Param("userId") Long userId,
            @Param("orderStatus") Integer orderStatus,
            @Param("limit") Integer limit
    );

    /**
     * 查询司机订单列表
     * 
     * @param driverId 司机ID
     * @param orderStatus 订单状态
     * @param limit 限制数量
     * @return 订单列表
     */
    List<Order> selectByDriverId(
            @Param("driverId") Long driverId,
            @Param("orderStatus") Integer orderStatus,
            @Param("limit") Integer limit
    );

    /**
     * 统计订单数量
     * 
     * @param orderStatus 订单状态
     * @param startTime 开始时间
     * @param endTime 结束时间
     * @return 订单数量
     */
    Long countOrders(
            @Param("orderStatus") Integer orderStatus,
            @Param("startTime") LocalDateTime startTime,
            @Param("endTime") LocalDateTime endTime
    );

    /**
     * 统计订单金额
     * 
     * @param orderStatus 订单状态
     * @param startTime 开始时间
     * @param endTime 结束时间
     * @return 订单总金额
     */
    BigDecimal sumOrderAmount(
            @Param("orderStatus") Integer orderStatus,
            @Param("startTime") LocalDateTime startTime,
            @Param("endTime") LocalDateTime endTime
    );

    /**
     * 查询订单统计数据
     * 
     * @param startTime 开始时间
     * @param endTime 结束时间
     * @return 统计数据
     */
    List<Map<String, Object>> selectOrderStatistics(
            @Param("startTime") LocalDateTime startTime,
            @Param("endTime") LocalDateTime endTime
    );

    /**
     * 更新订单状态
     * 
     * @param orderId 订单ID
     * @param orderStatus 订单状态
     * @param updateTime 更新时间
     * @return 影响行数
     */
    int updateOrderStatus(
            @Param("orderId") Long orderId,
            @Param("orderStatus") Integer orderStatus,
            @Param("updateTime") LocalDateTime updateTime
    );

    /**
     * 批量更新订单状态
     * 
     * @param orderIds 订单ID列表
     * @param orderStatus 订单状态
     * @param updateTime 更新时间
     * @return 影响行数
     */
    int batchUpdateOrderStatus(
            @Param("orderIds") List<Long> orderIds,
            @Param("orderStatus") Integer orderStatus,
            @Param("updateTime") LocalDateTime updateTime
    );

    /**
     * 查询超时未支付订单
     * 
     * @param timeoutMinutes 超时分钟数
     * @return 超时订单列表
     */
    List<Order> selectTimeoutOrders(@Param("timeoutMinutes") Integer timeoutMinutes);

    /**
     * 查询待分配司机的订单
     * 
     * @param limit 限制数量
     * @return 订单列表
     */
    List<Order> selectPendingAssignOrders(@Param("limit") Integer limit);

    /**
     * 分配司机
     * 
     * @param orderId 订单ID
     * @param driverId 司机ID
     * @param updateTime 更新时间
     * @return 影响行数
     */
    int assignDriver(
            @Param("orderId") Long orderId,
            @Param("driverId") Long driverId,
            @Param("updateTime") LocalDateTime updateTime
    );
}